package com.cysyz.web.modules.base.user.service;

import com.cysyz.mylib.dao.Conds;
import com.cysyz.mylib.dao.PagingResult;
import com.cysyz.mylib.utils.MD5;
import com.cysyz.mylib.utils.myassert.MyAssert;
import com.cysyz.mylib.utils.xsvmaker.XsvMaker;
import com.cysyz.mylib.utils.xsvmaker.impl.XsvMakerImpl;
import com.cysyz.web.modules.base.permission.domain.SysPrivilege;
import com.cysyz.web.modules.base.permission.domain.SysRole;
import com.cysyz.web.modules.base.permission.domain.SysSysrolePrivilege;
import com.cysyz.web.modules.base.permission.domain.SysUserRole;
import com.cysyz.web.modules.base.support.service.BaseService;
import com.cysyz.web.modules.base.user.domain.SysUser;
import com.cysyz.web.modules.base.validate.ColumnAndValue;
import com.cysyz.web.modules.base.validate.EntityInfoValidateService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by abroad on 2014/9/17.
 */
@Service
public class SysUserService extends BaseService {
	public SysUser getSysUserById(int pk) {
        return get(SysUser.class, pk);
    }

    public SysUser getSysUserByUserName(String userName) {
        MyAssert.notNull(userName);
        Conds conds = new Conds("SysUser");
        conds.addFilterByDefaultTableName("loginName", "=",userName);
//        conds.addFilterByDefaultTableName("state", "!=","lock");
        List<SysUser> list = list(SysUser.class, conds);

        SysUser result = null;
        if (list != null && !list.isEmpty()) {
            result = list.get(0);
        }
        return result;
    }

    public SysUser getUser(Long id) {
        SysUser sysUser = this.get(SysUser.class, id);
        for (SysUserRole o : sysUser.getSysUserRoles()) {
            o.getSysRole().getId();
        }
        return sysUser;
    }

    public List<SysUser> getAllUserOfRole(Long roleId) {
        Conds conds = new Conds("sysUserRole");
        conds.addFilterByDefaultTableName("sysRole.id", "=",roleId);

        List<SysUserRole> usersOfRole = list(SysUserRole.class, conds);

        List<SysUser> allUsers = list(SysUser.class);


        for (SysUser allUser : allUsers) {
            for (SysUserRole sysUserRole : usersOfRole) {
                if (sysUserRole.getSysUser().equals(allUser)) {
                    allUser.setRoleHasThisUser(true);
                    break;
                }

            }
        }
        return allUsers ;
    }

    public void addPrivilegesForRole(Long roleId, List<Long> sysPrivilegeIds) {
        this.m2MRelationshipMapping(SysRole.class, roleId, SysPrivilege.class, sysPrivilegeIds, SysSysrolePrivilege.class);
        Conds conds = new Conds("sysPrivilege");
        conds.addFilterByDefaultTableName("id", "in", sysPrivilegeIds);
        List<SysPrivilege> privilegesOfRole = this.list(SysPrivilege.class, conds);
        XsvMaker privileges = new XsvMakerImpl();
        for (SysPrivilege sysPrivilege : privilegesOfRole) {
            privileges.append(sysPrivilege.getCode());
        }
        SysRole sysRole = new SysRole();
        sysRole.setId(roleId);
        sysRole.setPrivileges(privileges.toString());
        this.merge(SysRole.class, sysRole, "privileges");
    }

    public void addUsersForRole(Long roleId, List<String> sysUserseIds) {
        this.m2MRelationshipMapping(SysRole.class, roleId, SysUser.class, sysUserseIds, SysUserRole.class);
    }

    public void addNewSysUser(SysUser sysUser, Long roleId) {
        sysUser.setState("unLock");
        sysUser.md5Password();
        setRoleOfUser(sysUser, roleId);
        this.save(sysUser);
    }

    private void setRoleOfUser(SysUser sysUser, Long roleId) {
        sysUser.getSysUserRoles().clear();
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setSysUser(sysUser);
        SysRole sysRole = new SysRole();
        sysRole.setId(roleId);
        sysUserRole.setSysRole(sysRole);
        sysUser.getSysUserRoles().add(sysUserRole);
    }

    public void editSysUser(SysUser sysUser, Long roleId) {
        SysUser sysUserDB = this.get(SysUser.class, sysUser.getId());
        List<Object> params = new ArrayList<>();
        params.add(sysUser.getId());
        this.executeSql("delete from FNM_SYS_USER_ROLE where user_id=?", params);
        if (sysUserDB.getPassword().equals(sysUser.getPassword())) {
            this.merge(SysUser.class, sysUser, "email", "mobile", "name");
        } else {
            sysUser.setPassword(MD5.MD5Encode(sysUser.getPassword()));
            this.merge(SysUser.class, sysUser, "email", "mobile", "password", "name");
        }

        setRoleOfUser(sysUserDB, roleId);
    }

    public void editSysUser(SysUser sysUser) {
        SysUser sysUserDB = this.get(SysUser.class, sysUser.getId());
        if (sysUserDB.getPassword().equals(sysUser.getPassword())) {
            this.merge(SysUser.class, sysUser, "email", "mobile", "name");
        } else {
            sysUser.setPassword(MD5.MD5Encode(sysUser.getPassword()));
            this.merge(SysUser.class, sysUser, "email", "mobile", "password", "name");

        }
    }

    public PagingResult<SysUser> getSysUserList(SysUser sysUser) {
        Conds conds = new Conds ("sysUser");
        if (sysUser != null) {
            conds.addFilterByDefaultTableName("createTime", ">=", sysUser.getCreateTimeBegin());
            conds.addFilterByDefaultTableName("createTime", "<=", sysUser.getCreateTimeEnd());

            conds.addFilterByDefaultTableName("lastLoginIp", "%like%", sysUser.getLastLoginIp());

            conds.addFilterByDefaultTableName("lastLoginTime", ">=", sysUser.getLastLoginTimeBegin());
            conds.addFilterByDefaultTableName("lastLoginTime", "<=", sysUser.getLastLoginTimeEnd());

            conds.addFilterByDefaultTableName("loginCount", ">=", sysUser.getLoginCountMin());
            conds.addFilterByDefaultTableName("loginCount", "<=", sysUser.getLoginCountMax());
            conds.addFilterByDefaultTableName("loginName", "%like%", sysUser.getLoginName());

            conds.addFilterByDefaultTableName("mobile", "%like%", sysUser.getMobile());
            conds.addFilterByDefaultTableName("email", "%like%", sysUser.getEmail());

            conds.addFilterByDefaultTableName("name", "%like%", sysUser.getName());

            conds.addFilterByDefaultTableName("state", "=", sysUser.getState());
            conds.setOrderBy("sysuser", "createTime", Conds.AscOrDesc.DESC);
        }
        return this.listPaging(SysUser.class, conds, sysUser.getPage(), sysUser.getMaxResult());
    }

    @Resource(type =EntityInfoValidateService.class )
    private EntityInfoValidateService entityInfoValidateService;

    /**
     * 验证用户是否已经存在
     * @param loginName
     * @return 如果存在返回true，否则返回false
     */
    public boolean validateLoginNameExits(String loginName) {
        return entityInfoValidateService.validateEntityExits(SysUser.class, new ColumnAndValue("loginName", loginName));
    }

    public void lock (Long userId) {
        MyAssert.notNull(userId);
        SysUser sysUser = this.get(SysUser.class, userId);
        sysUser.setState("lock");
    }

    public void unLock(Long userId) {
        MyAssert.notNull(userId);
        SysUser sysUser = this.get(SysUser.class, userId);
        sysUser.setState("unLock");
    }
}
